package com.cskaoyan.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.springframework.stereotype.Component;

/**
 * 切面类
 * @author stone
 * @date 2021/12/28 11:50
 */
@Component
public class CustomAspect {

    //before通知方法,方法名任意
    public void mybefore(JoinPoint joinPoint) {
        System.out.println("Before通知：正道的光1.0");
        Object proxy = joinPoint.getThis();   //proxy代理对象
        Object target = joinPoint.getTarget();//target委托类对象

        //拿到方法
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();  //Signature的name就是方法名

        //委托类方法执行的参数
        Object[] args = joinPoint.getArgs();

    }

    //after通知方法,方法名任意
    public void myafter() {
        System.out.println("After通知：照在大地上1.0");
    }

    //around通知方法 → 类似于InvocationHandler的invoke、类似于MethodInterceptor的invoke
    //要包含委托类方法的执行和增强两部分
    //around方法的返回值作为代理对象的执行结果 → 返回值为Object类型
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //比如说，我们将传给委托类方法的参数拿到
        Object[] args = proceedingJoinPoint.getArgs();
        //如果执行的是sayHello5我们做一个个性化的处理
        if ("sayHello5".equals(proceedingJoinPoint.getSignature().getName())) {
            //个性化的处理
            //原来传入的参数是songge → 现在给改一下 改成songge and ligenli
            args[0] += " and ligenli";

        }


        System.out.println("around的前半部分");

        //委托类方法的执行 → ProceedingJoinPoint
        //Object proceed = proceedingJoinPoint.proceed();//执行的是委托类的方法
        Object proceed = proceedingJoinPoint.proceed(args);//执行的是委托类的方法


        //增强
        System.out.println("around的后半部分");

        return proceed + " niupi";
    }

    //afterReturning可以获得委托类方法的执行结果，意味着能够接收到这个值 → 形参中以Object接收
    //形参名自己定义
    public void afterReturning(Object returnValue) {
        System.out.println("afterReturning通知：" + returnValue);
    }

    //afterThrowing通知 抛出异常的时候执行 → 可以获得你抛出的异常对象
    //使用Exception或Throwable来接收
    public void afterThrowing(Throwable e) {
        System.out.println("afterThrowing通知：" + e.getMessage());
    }

}
